package org.myhibernate.action;

import java.beans.PropertyDescriptor;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.myhibernate.core.Mapping;
import org.myhibernate.core.Mappings;
import org.myhibernate.core.Template;

public class ObjectAction 
{
	private Class cls=null;
	private HttpServletRequest request=null;
	private Object object=null;
	public ObjectAction() { 
	}
	public ObjectAction(HttpServletRequest request)
	{
		try {
			request.setCharacterEncoding("utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		this.request=request;
		if (request.getParameter("classname")!=null) {
			try {
				object=Class.forName(request.getParameter("classname")).newInstance();
				this.cls=object.getClass();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	public ObjectAction(Class cls,HttpServletRequest request)
	{
		try {
			request.setCharacterEncoding("utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		this.cls = cls;
		this.request=request;
		if (request.getParameter("classname")!=null) {
			try {
				object=Class.forName(request.getParameter("classname")).newInstance();
				this.cls=object.getClass();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	public void setObjectData(Object object,Map<String,Object> map)
	{
		if (object==null||(map==null)) {
			return;
		}
		Class cls=object.getClass();
		Mapping mapping=Mappings.getMapping(cls);
		//System.out.println("sname="+cls.getSimpleName());
		//System.out.println("Mappings="+Mappings.getMappingMap());
		//System.out.println();
		List<String> columnList=mapping.getPropertyColList();
		
		Field[] fields=cls.getDeclaredFields();
		Field field=null;
		String fieldName="";
		String fieldType="";
		Object dataValue=null;
		PropertyDescriptor descriptor=null;
		Method method =null;// descriptor.getReadMethod();
		for (int i = 0; i < fields.length; i++) 
		{
			field=fields[i];
			fieldName=field.getName();
			fieldType=field.getType().getSimpleName().toLowerCase();
			dataValue=map.get(fieldName);
			try {
				if (dataValue != null)
				{
					//System.out.println("set data,"+fieldName+"["+fieldType+"],"+dataValue+",cls="+cls);
					descriptor= new PropertyDescriptor(fieldName, cls);
					method = descriptor.getWriteMethod();
					if ("int".equals(fieldType))
					{
						Integer temp1=Integer.parseInt(dataValue+"");
						int tempValue=(int) temp1;
						dataValue=tempValue;
					} else if ("integer".equals(fieldType)){
						//method.invoke(object, Long.parseLong(dataValue+""));
						dataValue=Integer.parseInt(dataValue+"");
					}else if ("long".equals(fieldType)){
						//method.invoke(object, Long.parseLong(dataValue+""));
						dataValue=Long.parseLong(dataValue+"");
					} else if ("boolean".equals(fieldType)){
						//method.invoke(object, Boolean.parseBoolean(dataValue+""));
						dataValue=Boolean.parseBoolean(dataValue+"");
					}
					else if ("double".equals(fieldType)){
						//method.invoke(object, Double.parseDouble(dataValue+""));
						dataValue=Double.parseDouble(dataValue+"");
					}
					else if ("float".equals(fieldType)){
						//method.invoke(object, Float.parseFloat(dataValue+""));
						dataValue=Float.parseFloat(dataValue+"");
					}
					
					Method tempMethod = cls.getDeclaredMethod(mapping.getMethod_set_map().get(fieldName), field.getType()); // mapping.getPropertySetList().get(i)
					tempMethod.invoke(object, dataValue);
					
				}
				
			} catch (Exception e) 
			{
				System.out.println("ObjectAction Type dismatched:"+fieldName+"["+fieldType+"] for value:"+dataValue+"["+dataValue.getClass().getName()+"]");
				System.out.println("fieldName="+fieldName+",method="+mapping.getMethod_set_map().get(fieldName)+",fieldType="+field.getType().getName());
				e.printStackTrace();
			}
		}
	}
	public void setObjectData(Object object,HttpServletRequest request,Map<String, Object> extendMap)
	{
		Map<String,Object> dataMap=new HashMap<String, Object>();
		Map<String,Object> paramMap=request.getParameterMap();
		Iterator<String> iterator=paramMap.keySet().iterator();
		String key="";
		while (iterator.hasNext()) 
		{
			key=iterator.next();
			try {
				dataMap.put(key, URLDecoder.decode(request.getParameter(key)+"","utf-8"));
			} catch (UnsupportedEncodingException e) {
				//e.printStackTrace();
			}
		}
		if (extendMap !=null)
		{
			iterator=extendMap.keySet().iterator();
			while (iterator.hasNext()) 
			{
				key=iterator.next();
				dataMap.put(key, extendMap.get(key));
			}
		}
		setObjectData(object, dataMap);
	}
	public String saveOrUpdate() throws Exception
	{
		String idFieldName=Mappings.getMapping(getCls()).getId_Field();
		String id=request.getParameter(idFieldName);
		if (id==null) {
			id=request.getParameter("id")+"";
		}
		Template template=new Template(getCls());
		try {
			if (template.get(id)==null) 
			{
				setObjectData(object, request,null);//set values to the new object
				template.save(object);
			} else {
				object=template.get(id);//get old object
				setObjectData(object, request,null);//set values to the old object
				template.update(object);
			}
			return "{'result':'ok','message':'','id':'"+id+"'}";
		} catch (Exception e) {
			return "{'result':'no','message':'"+e.toString()+"','id':'"+id+"'}";
		}finally{
			template.close();
		}
	}
	public String delete(Object id) throws Exception
	{
		if (id==null) {
			return "{'result':'no','message':'id is null','id':'"+id+"'}";
		}
		Template template=new Template(getCls());
		try {
			int count=0;
			if (id instanceof String) 
			{
				String tempId=id+"";
				String[] ids=tempId.split(",");
				for (int i = 0; i < ids.length; i++) 
				{
					if (template.get(ids[i]+"")!=null)
					{
						template.delete(ids[i]);
						count++;
					}
				}
			} else {
				template.delete(id);
				count++;
			}
			
			return "{'result':'ok','message':'','id':'"+id+"','count':'"+count+"'}";
		} catch (Exception e) {
			return "{'result':'no','message':'"+e.toString()+"','id':'"+id+"'}";
		}finally{
			template.close();
		}
	}
	public String delete() throws Exception
	{
		String idFieldName=Mappings.getMapping(getCls()).getId_Field();
		String id=request.getParameter(idFieldName);
		if (id==null) {
			id=request.getParameter("id");
		}
		if (id==null) {
			return "{'result':'no','message':'id is null','id':'"+id+"'}";
		}
		Template template=new Template(getCls());
		try {
			int count=0;
			if (id instanceof String) 
			{
				String tempId=id+"";
				String[] ids=tempId.split(",");
				for (int i = 0; i < ids.length; i++) 
				{
					if (template.get(ids[i]+"")!=null)
					{
						template.delete(ids[i]);
						count++;
					}
				}
			} else {
				template.delete(id);
				count++;
			}
			
			return "{'result':'ok','message':'','id':'"+id+"','count':'"+count+"'}";
		} catch (Exception e) {
			return "{'result':'no','message':'"+e.toString()+"','id':'"+id+"'}";
		}finally{
			template.close();
		}
	}
	public Object invoke(Object obj,String methodName,Object... args) throws Exception
	{
		Method[] methods=obj.getClass().getDeclaredMethods();
		Object result=null;
		for (int i = 0; i < methods.length; i++) 
		{
			Method method=methods[i];
			if (methodName.equals(method.getName()))
			{
				try {
					result=method.invoke(obj, args);
					return result;
				} catch (Exception e) {
					e.printStackTrace();
					throw new RuntimeException(e.toString());
				}
			}
		}
		return result;
	}
	public Class getCls() {
		return cls;
	}
	public HttpServletRequest getRequest() {
		return request;
	}
	public Object getObject() {
		return object;
	}
	
}
